package com.yohann.boot.common.page;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yohann.boot.common.annotation.TableHead;
import lombok.Data;

import java.lang.reflect.Field;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;

/**
 * 分页信息
 *
 * @author Yeung Wah
 * @since 2021/7/9
 */
@Data
public class PageInfo<T> {
    /**
     * 总数
     */
    private long total;
    /**
     * 页码
     */
    private long pageNumber;
    /**
     * 页宽
     */
    private long pageSize;
    /**
     * 数据
     */
    private List<T> rows;
    /**
     * 表格头部信息
     */
    private List<TableHeader> tableHeaders;

    /**
     * 私有构造 只能通过build方法构建
     */
    private PageInfo(Page<T> page, List<TableHeader> tableHeaders) {
        this.total = page.getTotal();
        this.pageNumber = page.getCurrent();
        this.pageSize = page.getSize();
        this.rows = page.getRecords();
        this.tableHeaders = tableHeaders;
    }

    /**
     * 页面table信息
     */
    @Data
    private static class TableHeader {
        private String label;
        private String value;
    }

    /**
     * 构建不含有表头的分页信息
     *
     * @param page 分页信息
     * @return 分页信息
     */
    public static <T> PageInfo<T> buildPage(Page<T> page) {
        return new PageInfo<>(page, null);
    }

    /**
     * 构建含有表头的分页信息
     *
     * @param page  分页信息
     * @param clazz 数据类型字节码
     * @return 分页信息
     */
    public static <T> PageInfo<T> buildPage(Page<T> page, Class<T> clazz) {
        List<TableHeader> tableHeaders = new LinkedList<>();

        //通过反射获取表头
        for (Field field : clazz.getDeclaredFields()) {
            TableHead tableHead = field.getAnnotation(TableHead.class);
            if (Objects.nonNull(tableHead)) {
                TableHeader tableHeader = new TableHeader();
                tableHeader.setLabel(tableHead.value());
                tableHeader.setValue(field.getName());
                tableHeaders.add(tableHeader);
            }
        }

        return new PageInfo<>(page, tableHeaders);
    }
}